#include "main.h"

// 要求将所有代码写在本文件内
// 必须实现下列函数。可以自行增加别的函数。
// 请勿修改由老师所提供的main.h文件的内容。
// 初始化名为s的栈，初始化成功，返回0，否则返回1。
int init_stack(Stack * s) {
  //*s = malloc(sizeof(struct stack));

  (*s) = malloc(sizeof(struct stack));
    int * p = (int*)malloc(STACK_MAX_SIZE*sizeof(int));
    (*s)->base = p;

    if(!(*s)->base){
    	return 1;
	}

    (*s)->top = (*s)->base ;
    (*s)->number_of_elements = STACK_MAX_SIZE;
    return 0;
}

// 入栈。返回值表示是否压栈成功：0，成功；1，不成功。
int push(Stack s, char operator_or_operand) {
	//栈满
	if(s->top - s->base >= s->number_of_elements){
		return 1;
	}else{
		*(s->top) = operator_or_operand;
		s->top++;
		return 0;
	}
}

// 出栈。返回值表示是否出栈成功：0，成功，1，不成功。
int pop(Stack s, char* p_operator_or_operand) {
	//栈空
	if(s->top == s->base){
		return 1;
	}
	s->top--;
	*p_operator_or_operand = *(s->top);
    return 0;
}

// 只返回栈顶元素，通过result变量返回栈顶元素的值。函数返回值用于表示执行状态：0，成功；1，不成功。
int get_top(Stack s, char * result) {
	//栈空
	if(s->top == s->base){
		return 1;
	} else{
		*result = *(s->top-1);
        return 0;
	}


}

// 判断字符symbol是否操作符。如果symbol是操作符，返回1，否则返回0。
bool is_operator(char symbol) {
	char operator[7] = {'+','-','*','/','(',')','#'};
	int i;
    for(i= 0; i<7; ++i)
    {
        if(operator[i] == symbol)
        {
            return 1;
        }
    }
    return 0;
}

// 判断字符symbol是否操作数。如果symbol是操作数，返回1，否则返回0。
bool is_operand(char symbol) {
	char operand[10] = {'0','1','2','3','4','5','6','7','8','9'};
	int i;
    for(i= 0; i<10; ++i)
    {
        if(operand[i] == symbol)
        {
            return 1;
        }
    }
    return 0;
}

int compare_operators(char first,char two) {
    int i, j;
    char x[][7] = {
            /*优先级制作成一张表格*/
            {'>', '>', '<', '<', '<', '>', '>'},
            {'>', '>', '<', '<', '<', '>', '>'},
            {'>', '>', '>', '>', '<', '>', '>'},
            {'>', '>', '>', '>', '<', '>', '>'},
            {'<', '<', '<', '<', '<', '=', '0'},
            {'>', '>', '>', '>', '0', '>', '>'},
            {'<', '<', '<', '<', '<', '0', '='}
    };
    switch(first){
        case '+': i=0;
		 break;
        case '-': i=1;
		 break;
        case '*': i=2;
		 break;
        case '/': i=3;
		 break;
        case '(': i=4;
		 break;
        case ')': i=5;
		 break;
        case '#': i=6;
		 break;
    }
    switch (two) {
        case '+':j = 0;
		 break;
        case '-':j = 1;
		 break;
        case '*':j = 2;
	 	 break;
        case '/':j = 3;
		 break;
        case '(':j = 4;
		 break;
        case ')':j = 5;
		 break;
        case '#':j = 6;
		 break;
    }
    switch (x[i][j]) {
        case '>':
            return 1;
        case '<':
            return -1;
        case '=':
            return 0;
    }
}

int caculate(char operator, char left, char right, int * result) {
    int i , j;
    switch (left) {
        case'0': i = 0;break;
        case'1': i = 1;break;
        case'2': i = 2;break;
        case'3': i = 3;break;
        case'4': i = 4;break;
        case'5': i = 5;break;
        case'6': i = 6;break;
        case'7': i = 7;break;
        case'8': i = 8;break;
        case'9': i = 9;break;
    }
    switch (right) {
        case'0': j = 0;
		break;
        case'1': j = 1;
		break;
        case'2': j = 2;
		break;
        case'3': j = 3;
		break;
        case'4': j = 4;
		break;
        case'5': j = 5;
		break;
        case'6': j = 6;
		break;
        case'7': j = 7;
		break;
        case'8': j = 8;
		break;
        case'9': j = 9;
		break;
    }

    switch (operator) {
        case '+':*result = i + j;
		 break;
        case '-':*result = i - j;
		 break;
        case '*':*result = i * j;
		 break;

        case '/':
            if (j!=0) {
                *result = i / j;
            }
            else{
                exit(0);
            }
            break;
    }
    return 0;
}


// 最主要的函数，用于计算表达式的值，比如#3*(2+6)/4#。
// 返回值表示求值状态：0，合法表达式，成功求值；1，表达式不合法。
// result变量用于返回计算结果。
int evaluate(char * expression, int * result) {
	Stack a;
    Stack b;
    char left;
    char right;
    init_stack(&a);
    init_stack(&b);

    int char_position = 0;
    push(a, expression[char_position]);
    char_position +=1;
    char top;
    char w = expression[char_position];
    //分别判断expression中每个字符的格式
    while(w != '#' || top != '#')
    {
        if(is_operand(w))
        {
            push(b, w);
            char_position += 1;
            w = expression[char_position];
        }
        if(is_operator(w))
        {   char c;
            get_top(a, &c);
            char Total;
            int RESULT;
            switch (compare_operators(c,w)) {
                case -1:
                    push(a, w);
                    w = expression[++char_position];
                    break;
                case 0:
                    pop(a, &c);
                    w = expression[++char_position];
                    break;
                case 1:
                    pop(b, &right);
                    pop(b, &left);
                    pop(a, &c);
                    if (c == '#' || left == 0){
                        *result = 1;
                        return *result;
                    }else {
                        caculate(c, left, right, &RESULT);
                        Total = RESULT + 48;
                        push(b, Total);
                    }
                    break;
            }
        }
        get_top(a, &top);
    }
    get_top(b, &top);
    *result = top - 48;
    return *result;
}

// 编写你们组自己使用的测试代码
int main(int argc, char * argv[]) {
  int result;
    int is_exp_valid = evaluate("#3*(2+6)/4#", &result);
    printf("result:%d",is_exp_valid);
}